package com.example.ftpfilesync.service;

import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;

@Service
public class FileStateChecker {

    private static final Logger logger = LoggerFactory.getLogger(FileStateChecker.class);
    
    // 使用 ConcurrentHashMap 保证线程安全
    private final ConcurrentHashMap<String, FileInfo> fileStateMap = new ConcurrentHashMap<>();

    // 文件信息内部类
    private static class FileInfo {
        long size;
        long lastModified;
        long lastCheckTime;
        
        FileInfo(long size, long lastModified, long lastCheckTime) {
            this.size = size;
            this.lastModified = lastModified;
            this.lastCheckTime = lastCheckTime;
        }
    }

    /**
     * 检查FTP目录下的文件是否稳定（没有变化）
     *
     * @param ftpClient FTP客户端
     * @param directory 要检查的目录
     * @return true表示文件已经稳定，false表示仍在变化中
     * @throws IOException IO异常
     */
    public boolean isDirectoryStable(FTPClient ftpClient, String directory) throws IOException {
        ftpClient.changeWorkingDirectory(directory);
        FTPFile[] files = ftpClient.listFiles();

        long currentTotalSize = 0;
        long currentLatestModified = 0;

        // 计算当前目录下所有文件的总大小和最新修改时间
        for (FTPFile file : files) {
            if (file.isFile()) {
                currentTotalSize += file.getSize();
                if (file.getTimestamp() != null && file.getTimestamp().getTimeInMillis() > currentLatestModified) {
                    currentLatestModified = file.getTimestamp().getTimeInMillis();
                }
            } else if (file.isDirectory() && !".".equals(file.getName()) && !"..".equals(file.getName())) {
                // 递归检查子目录
                String subDirectory = directory + "/" + file.getName();
                isDirectoryStable(ftpClient, subDirectory);
            }
        }

        // 构造唯一标识符
        String identifier = directory;
        long currentTime = System.currentTimeMillis();

        // 获取上次检查时的记录
        FileInfo lastInfo = fileStateMap.get(identifier);
        if (lastInfo == null) {
            // 第一次检查，记录当前状态
            fileStateMap.put(identifier, new FileInfo(currentTotalSize, currentLatestModified, currentTime));
            logger.debug("首次检查目录 {}: 大小={}, 最后修改时间={}", directory, currentTotalSize, currentLatestModified);
            return false;
        }

        // 更新检查时间
        lastInfo.lastCheckTime = currentTime;

        // 如果大小发生变化，则认为仍在变化中
        if (lastInfo.size != currentTotalSize) {
            fileStateMap.put(identifier, new FileInfo(currentTotalSize, currentLatestModified, currentTime));
            logger.info("目录 {} 仍在变化中: 大小从 {} 变为 {}", directory, lastInfo.size, currentTotalSize);
            return false;
        }

        // 检查是否已经稳定足够长时间（至少10秒）
        boolean isStable = (currentTime - lastInfo.lastModified) >= 10000;
        
        if (!isStable) {
            logger.info("目录 {} 仍在变化中: 最近有文件修改，距离上次修改 {} 毫秒", directory, (currentTime - lastInfo.lastModified));
        } else {
            logger.debug("目录 {} 已经稳定: 距离上次修改 {} 毫秒", directory, (currentTime - lastInfo.lastModified));
        }
        
        return isStable;
    }

    /**
     * 检查FTP文件是否稳定（没有变化）
     *
     * @param ftpClient FTP客户端
     * @param filePath 文件路径
     * @param file FTP文件对象
     * @return true表示文件已经稳定，false表示仍在变化中
     */
    public boolean isFileStable(FTPClient ftpClient, String filePath, FTPFile file) {
        long currentSize = file.getSize();
        long currentModified = file.getTimestamp() != null ? file.getTimestamp().getTimeInMillis() : 0;

        // 构造唯一标识符
        String identifier = filePath;
        long currentTime = System.currentTimeMillis();

        // 获取上次检查时的记录
        FileInfo lastInfo = fileStateMap.get(identifier);
        if (lastInfo == null) {
            // 第一次检查，记录当前状态
            fileStateMap.put(identifier, new FileInfo(currentSize, currentModified, currentTime));
            logger.debug("首次检查文件 {}: 大小={}, 最后修改时间={}", filePath, currentSize, currentModified);
            return false;
        }

        // 更新检查时间
        lastInfo.lastCheckTime = currentTime;

        // 如果大小或修改时间发生变化，则认为仍在变化中
        if (lastInfo.size != currentSize || lastInfo.lastModified != currentModified) {
            fileStateMap.put(identifier, new FileInfo(currentSize, currentModified, currentTime));
            logger.info("文件 {} 仍在变化中: 大小从 {} 变为 {} 或修改时间从 {} 变为 {}", 
                filePath, lastInfo.size, currentSize, lastInfo.lastModified, currentModified);
            return false;
        }

        // 检查是否已经稳定足够长时间（至少10秒）
        boolean isStable = (currentTime - lastInfo.lastModified) >= 10000;
        
        if (!isStable) {
            logger.info("文件 {} 仍在变化中: 最近有修改，距离上次修改 {} 毫秒", filePath, (currentTime - lastInfo.lastModified));
        } else {
            logger.debug("文件 {} 已经稳定: 距离上次修改 {} 毫秒", filePath, (currentTime - lastInfo.lastModified));
        }
        
        return isStable;
    }

    /**
     * 检查本地目录下的文件是否稳定（没有变化）
     *
     * @param directory 要检查的目录
     * @return true表示文件已经稳定，false表示仍在变化中
     */
    public boolean isLocalDirectoryStable(File directory) {
        File[] files = directory.listFiles();
        
        if (files == null) {
            return true;
        }

        long currentTotalSize = 0;
        long currentLatestModified = 0;

        // 计算当前目录下所有文件的总大小和最新修改时间
        for (File file : files) {
            if (file.isFile()) {
                currentTotalSize += file.length();
                if (file.lastModified() > currentLatestModified) {
                    currentLatestModified = file.lastModified();
                }
            } else if (file.isDirectory()) {
                // 递归检查子目录
                if (isLocalDirectoryStable(file)) {
                    currentTotalSize += file.length();
                }
            }
        }

        // 构造唯一标识符
        String identifier = directory.getAbsolutePath();
        long currentTime = System.currentTimeMillis();

        // 获取上次检查时的记录
        FileInfo lastInfo = fileStateMap.get(identifier);
        if (lastInfo == null) {
            // 第一次检查，记录当前状态
            fileStateMap.put(identifier, new FileInfo(currentTotalSize, currentLatestModified, currentTime));
            logger.debug("首次检查本地目录 {}: 大小={}, 最后修改时间={}", directory.getAbsolutePath(), currentTotalSize, currentLatestModified);
            return false;
        }

        // 更新检查时间
        lastInfo.lastCheckTime = currentTime;

        // 如果大小发生变化，则认为仍在变化中
        if (lastInfo.size != currentTotalSize) {
            fileStateMap.put(identifier, new FileInfo(currentTotalSize, currentLatestModified, currentTime));
            logger.info("目录 {} 仍在变化中: 大小从 {} 变为 {}", directory.getAbsolutePath(), lastInfo.size, currentTotalSize);
            return false;
        }

        // 检查是否已经稳定足够长时间（至少10秒）
        boolean isStable = (currentTime - lastInfo.lastModified) >= 10000;
        
        if (!isStable) {
            logger.info("目录 {} 仍在变化中: 最近有文件修改，距离上次修改 {} 毫秒", directory.getAbsolutePath(), (currentTime - lastInfo.lastModified));
        } else {
            logger.debug("目录 {} 已经稳定: 距离上次修改 {} 毫秒", directory.getAbsolutePath(), (currentTime - lastInfo.lastModified));
        }
        
        return isStable;
    }

    /**
     * 检查本地文件是否稳定（没有变化）
     *
     * @param file 要检查的文件
     * @return true表示文件已经稳定，false表示仍在变化中
     */
    public boolean isLocalFileStable(File file) {
        long currentSize = file.length();
        long currentModified = file.lastModified();

        // 构造唯一标识符
        String identifier = file.getAbsolutePath();
        long currentTime = System.currentTimeMillis();

        // 获取上次检查时的记录
        FileInfo lastInfo = fileStateMap.get(identifier);
        if (lastInfo == null) {
            // 第一次检查，记录当前状态
            fileStateMap.put(identifier, new FileInfo(currentSize, currentModified, currentTime));
            logger.debug("首次检查本地文件 {}: 大小={}, 最后修改时间={}", file.getAbsolutePath(), currentSize, currentModified);
            return false;
        }

        // 更新检查时间
        lastInfo.lastCheckTime = currentTime;

        // 如果大小或修改时间发生变化，则认为仍在变化中
        if (lastInfo.size != currentSize || lastInfo.lastModified != currentModified) {
            fileStateMap.put(identifier, new FileInfo(currentSize, currentModified, currentTime));
            logger.info("文件 {} 仍在变化中: 大小从 {} 变为 {} 或修改时间从 {} 变为 {}", 
                file.getAbsolutePath(), lastInfo.size, currentSize, lastInfo.lastModified, currentModified);
            return false;
        }

        // 检查是否已经稳定足够长时间（至少10秒）
        boolean isStable = (currentTime - lastInfo.lastModified) >= 10000;
        
        if (!isStable) {
            logger.info("文件 {} 仍在变化中: 最近有修改，距离上次修改 {} 毫秒", file.getAbsolutePath(), (currentTime - lastInfo.lastModified));
        } else {
            logger.debug("文件 {} 已经稳定: 距离上次修改 {} 毫秒", file.getAbsolutePath(), (currentTime - lastInfo.lastModified));
        }
        
        return isStable;
    }

    /**
     * 清除目录检查记录
     *
     * @param directory 目录路径
     */
    public void clearDirectoryRecord(String directory) {
        fileStateMap.remove(directory);
    }
}